import numpy as np
import pandas as pd
import seaborn as sns
import itertools
import os
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.layers import Dense, Activation
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.metrics import categorical_crossentropy
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing import image
from tensorflow.keras.models import Model
from tensorflow.keras.applications import imagenet_utils
from sklearn.metrics import confusion_matrix, precision_score, recall_score, accuracy_score, f1_score
mobile = tf.keras.applications.mobilenet.MobileNet()
Metal device set to: Apple M2
2023-03-17 12:02:54.504952: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:305] Could not identify NUMA node of platform GPU ID 0, defaulting to 0. Your kernel may not have been built with NUMA support. 2023-03-17 12:02:54.505041: I tensorflow/core/common_runtime/pluggable_device/pluggable_device_factory.cc:271] Created TensorFlow device (/job:localhost/replica:0/task:0/device:GPU:0 with 0 MB memory) -> physical PluggableDevice (device: 0, name: METAL, pci bus id: <undefined>)
train_dir = "/Users/preslav/Downloads/cw_cop528/imageset/train"
test_dir = "/Users/preslav/Downloads/cw_cop528/imageset/val"
# import data, whilist preprocessing pixel values in the range [-1, 1]
train_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.mobilenet.preprocess_input, validation_split=0.2).flow_from_directory(
directory=train_dir, target_size = (224, 224), subset = "training" ,batch_size = 32, seed = 2)
validation_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.mobilenet.preprocess_input, validation_split=0.2).flow_from_directory(
directory=train_dir, target_size = (224, 224), subset = "validation" ,batch_size = 32, seed = 2)
test_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.mobilenet.preprocess_input).flow_from_directory(
directory=test_dir, target_size = (224, 224),batch_size = 32, seed = 2, shuffle = False)
Found 7578 images belonging to 10 classes. Found 1891 images belonging to 10 classes. Found 3925 images belonging to 10 classes.
# import of the class labels names and their total number
class_names = list(train_batches.class_indices.keys())
num_classes = len(class_names)
print(class_names)
print(num_classes)
['building', 'dog', 'fish', 'gas_station', 'golf', 'musician', 'parachute', 'radio', 'saw', 'vehicle'] 10
# pixel values are brough from standartization to normalization,
# so that they can be propertly displayed
img, lbl = next(train_batches)
img_disp = (img + 1)/2
# display image
plt.imshow(img_disp[24])
plt.tight_layout()
plt.show()
# get predictions
predictions_new = mobile.predict(img_disp)
results_new = imagenet_utils.decode_predictions(predictions_new)
# display the highest 5 predictions in a dataframe
mobile_net_predictions = pd.DataFrame(results_new[24])
mobile_net_predictions.columns = ["actual_label", "preedicted_label", "propability"]
display(mobile_net_predictions)
2023-03-17 12:02:55.467408: W tensorflow/core/platform/profile_utils/cpu_utils.cc:128] Failed to get CPU frequency: 0 Hz 2023-03-17 12:02:55.592597: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
1/1 [==============================] - 0s 366ms/step
| actual_label | preedicted_label | propability | |
|---|---|---|---|
| 0 | n04208210 | shovel | 0.161206 |
| 1 | n03000684 | chain_saw | 0.114571 |
| 2 | n04461696 | tow_truck | 0.066798 |
| 3 | n03594945 | jeep | 0.064021 |
| 4 | n02493793 | spider_monkey | 0.061292 |
# this part of the code has been inspired by the following tutorial:
# https://www.youtube.com/watch?v=Zrt76AIbeh4
# freeze all the layers, so they are not trainable and no weights nor biases are be updated
for layer in mobile.layers:
layer.trainable = False
# replace last 5 layers with our own 2 dense layers
x_remove_layers = mobile.layers[-5].output
output_non_trainable = Dense(units = 10, activation = "softmax")(x_remove_layers)
output_non_trainable = tf.keras.layers.Reshape(target_shape=(10,))(output_non_trainable)
# create module, that takes MobileNet and transforms it with our desired final layers,
# in place of the MobileNet's last 5 layers
model_non_trainable = Model(inputs = mobile.input, outputs = output_non_trainable)
model_non_trainable.compile(optimizer = Adam(learning_rate = 0.0001),
loss = "categorical_crossentropy",
metrics = ["accuracy"])
# it can be noticed, that there are onlt 10250 trainable parameters,
# which come only from the layers added by us
model_non_trainable.summary()
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 224, 224, 3)] 0
conv1 (Conv2D) (None, 112, 112, 32) 864
conv1_bn (BatchNormalizatio (None, 112, 112, 32) 128
n)
conv1_relu (ReLU) (None, 112, 112, 32) 0
conv_dw_1 (DepthwiseConv2D) (None, 112, 112, 32) 288
conv_dw_1_bn (BatchNormaliz (None, 112, 112, 32) 128
ation)
conv_dw_1_relu (ReLU) (None, 112, 112, 32) 0
conv_pw_1 (Conv2D) (None, 112, 112, 64) 2048
conv_pw_1_bn (BatchNormaliz (None, 112, 112, 64) 256
ation)
conv_pw_1_relu (ReLU) (None, 112, 112, 64) 0
conv_pad_2 (ZeroPadding2D) (None, 113, 113, 64) 0
conv_dw_2 (DepthwiseConv2D) (None, 56, 56, 64) 576
conv_dw_2_bn (BatchNormaliz (None, 56, 56, 64) 256
ation)
conv_dw_2_relu (ReLU) (None, 56, 56, 64) 0
conv_pw_2 (Conv2D) (None, 56, 56, 128) 8192
conv_pw_2_bn (BatchNormaliz (None, 56, 56, 128) 512
ation)
conv_pw_2_relu (ReLU) (None, 56, 56, 128) 0
conv_dw_3 (DepthwiseConv2D) (None, 56, 56, 128) 1152
conv_dw_3_bn (BatchNormaliz (None, 56, 56, 128) 512
ation)
conv_dw_3_relu (ReLU) (None, 56, 56, 128) 0
conv_pw_3 (Conv2D) (None, 56, 56, 128) 16384
conv_pw_3_bn (BatchNormaliz (None, 56, 56, 128) 512
ation)
conv_pw_3_relu (ReLU) (None, 56, 56, 128) 0
conv_pad_4 (ZeroPadding2D) (None, 57, 57, 128) 0
conv_dw_4 (DepthwiseConv2D) (None, 28, 28, 128) 1152
conv_dw_4_bn (BatchNormaliz (None, 28, 28, 128) 512
ation)
conv_dw_4_relu (ReLU) (None, 28, 28, 128) 0
conv_pw_4 (Conv2D) (None, 28, 28, 256) 32768
conv_pw_4_bn (BatchNormaliz (None, 28, 28, 256) 1024
ation)
conv_pw_4_relu (ReLU) (None, 28, 28, 256) 0
conv_dw_5 (DepthwiseConv2D) (None, 28, 28, 256) 2304
conv_dw_5_bn (BatchNormaliz (None, 28, 28, 256) 1024
ation)
conv_dw_5_relu (ReLU) (None, 28, 28, 256) 0
conv_pw_5 (Conv2D) (None, 28, 28, 256) 65536
conv_pw_5_bn (BatchNormaliz (None, 28, 28, 256) 1024
ation)
conv_pw_5_relu (ReLU) (None, 28, 28, 256) 0
conv_pad_6 (ZeroPadding2D) (None, 29, 29, 256) 0
conv_dw_6 (DepthwiseConv2D) (None, 14, 14, 256) 2304
conv_dw_6_bn (BatchNormaliz (None, 14, 14, 256) 1024
ation)
conv_dw_6_relu (ReLU) (None, 14, 14, 256) 0
conv_pw_6 (Conv2D) (None, 14, 14, 512) 131072
conv_pw_6_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_6_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_7 (DepthwiseConv2D) (None, 14, 14, 512) 4608
conv_dw_7_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_dw_7_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_7 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_7_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_7_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_8 (DepthwiseConv2D) (None, 14, 14, 512) 4608
conv_dw_8_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_dw_8_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_8 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_8_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_8_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_9 (DepthwiseConv2D) (None, 14, 14, 512) 4608
conv_dw_9_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_dw_9_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_9 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_9_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_9_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_10 (DepthwiseConv2D (None, 14, 14, 512) 4608
)
conv_dw_10_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_dw_10_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_10 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_10_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_pw_10_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_11 (DepthwiseConv2D (None, 14, 14, 512) 4608
)
conv_dw_11_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_dw_11_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_11 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_11_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_pw_11_relu (ReLU) (None, 14, 14, 512) 0
conv_pad_12 (ZeroPadding2D) (None, 15, 15, 512) 0
conv_dw_12 (DepthwiseConv2D (None, 7, 7, 512) 4608
)
conv_dw_12_bn (BatchNormali (None, 7, 7, 512) 2048
zation)
conv_dw_12_relu (ReLU) (None, 7, 7, 512) 0
conv_pw_12 (Conv2D) (None, 7, 7, 1024) 524288
conv_pw_12_bn (BatchNormali (None, 7, 7, 1024) 4096
zation)
conv_pw_12_relu (ReLU) (None, 7, 7, 1024) 0
conv_dw_13 (DepthwiseConv2D (None, 7, 7, 1024) 9216
)
conv_dw_13_bn (BatchNormali (None, 7, 7, 1024) 4096
zation)
conv_dw_13_relu (ReLU) (None, 7, 7, 1024) 0
conv_pw_13 (Conv2D) (None, 7, 7, 1024) 1048576
conv_pw_13_bn (BatchNormali (None, 7, 7, 1024) 4096
zation)
conv_pw_13_relu (ReLU) (None, 7, 7, 1024) 0
global_average_pooling2d (G (None, 1, 1, 1024) 0
lobalAveragePooling2D)
dense (Dense) (None, 1, 1, 10) 10250
reshape (Reshape) (None, 10) 0
=================================================================
Total params: 3,239,114
Trainable params: 10,250
Non-trainable params: 3,228,864
_________________________________________________________________
epochs = 20
history_non_trainable = model_non_trainable.fit(x = train_batches,
validation_data = validation_batches,
epochs = epochs)
Epoch 1/20
2023-03-17 12:02:56.755772: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
237/237 [==============================] - ETA: 0s - loss: 1.6925 - accuracy: 0.4677
2023-03-17 12:03:15.694863: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
237/237 [==============================] - 24s 99ms/step - loss: 1.6925 - accuracy: 0.4677 - val_loss: 0.8438 - val_accuracy: 0.8006 Epoch 2/20 237/237 [==============================] - 23s 96ms/step - loss: 0.5574 - accuracy: 0.8853 - val_loss: 0.4161 - val_accuracy: 0.9138 Epoch 3/20 237/237 [==============================] - 23s 96ms/step - loss: 0.3160 - accuracy: 0.9390 - val_loss: 0.2803 - val_accuracy: 0.9418 Epoch 4/20 237/237 [==============================] - 23s 97ms/step - loss: 0.2241 - accuracy: 0.9543 - val_loss: 0.2171 - val_accuracy: 0.9513 Epoch 5/20 237/237 [==============================] - 23s 97ms/step - loss: 0.1746 - accuracy: 0.9613 - val_loss: 0.1782 - val_accuracy: 0.9582 Epoch 6/20 237/237 [==============================] - 23s 96ms/step - loss: 0.1433 - accuracy: 0.9679 - val_loss: 0.1542 - val_accuracy: 0.9651 Epoch 7/20 237/237 [==============================] - 23s 96ms/step - loss: 0.1210 - accuracy: 0.9741 - val_loss: 0.1340 - val_accuracy: 0.9699 Epoch 8/20 237/237 [==============================] - 23s 96ms/step - loss: 0.1046 - accuracy: 0.9782 - val_loss: 0.1206 - val_accuracy: 0.9720 Epoch 9/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0916 - accuracy: 0.9809 - val_loss: 0.1091 - val_accuracy: 0.9757 Epoch 10/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0810 - accuracy: 0.9838 - val_loss: 0.1012 - val_accuracy: 0.9757 Epoch 11/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0723 - accuracy: 0.9860 - val_loss: 0.0947 - val_accuracy: 0.9751 Epoch 12/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0650 - accuracy: 0.9871 - val_loss: 0.0906 - val_accuracy: 0.9799 Epoch 13/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0589 - accuracy: 0.9892 - val_loss: 0.0845 - val_accuracy: 0.9788 Epoch 14/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0535 - accuracy: 0.9900 - val_loss: 0.0813 - val_accuracy: 0.9799 Epoch 15/20 237/237 [==============================] - 23s 97ms/step - loss: 0.0486 - accuracy: 0.9914 - val_loss: 0.0760 - val_accuracy: 0.9794 Epoch 16/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0446 - accuracy: 0.9926 - val_loss: 0.0737 - val_accuracy: 0.9794 Epoch 17/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0408 - accuracy: 0.9937 - val_loss: 0.0706 - val_accuracy: 0.9794 Epoch 18/20 237/237 [==============================] - 23s 97ms/step - loss: 0.0375 - accuracy: 0.9937 - val_loss: 0.0688 - val_accuracy: 0.9804 Epoch 19/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0344 - accuracy: 0.9947 - val_loss: 0.0660 - val_accuracy: 0.9804 Epoch 20/20 237/237 [==============================] - 23s 96ms/step - loss: 0.0316 - accuracy: 0.9955 - val_loss: 0.0642 - val_accuracy: 0.9820
# Graphical evaluation of training performance
acc = history_non_trainable.history['accuracy']
val_acc = history_non_trainable.history['val_accuracy']
loss = history_non_trainable.history['loss']
val_loss = history_non_trainable.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(11, 8))
plt.subplots_adjust(hspace = .3)
plt.subplot(2, 1, 1)
plt.plot(epochs_range, acc, label = 'Training Accuracy', color = "orange")
plt.plot(epochs_range, val_acc, label = 'Validation Accuracy', color = "blue")
plt.legend(loc = 'best')
plt.xlabel('Epochs')
plt.title('Training and Validation Accuracy', size = 13)
plt.subplot(2, 1, 2)
plt.plot(epochs_range, loss, label = 'Training Loss', color = "orange")
plt.plot(epochs_range, val_loss, label = 'Validation Loss', color = "blue")
plt.legend(loc = 'best')
plt.title('Training and Validation Loss', size = 13)
plt.xlabel('Epochs')
plt.suptitle("Transfer learning (non-trainable)", size=15)
plt.show()
# Test loss and accuracy measurments
test_loss, test_acc = model_non_trainable.evaluate(test_batches)
print('Test loss:', test_loss)
print('Test accuracy:', test_acc)
123/123 [==============================] - 10s 77ms/step - loss: 0.0574 - accuracy: 0.9839 Test loss: 0.057424888014793396 Test accuracy: 0.9839491248130798
# getting prediction labales by running the softmax results in argmax
test_labels = test_batches.classes
y_pred = model_non_trainable.predict(test_batches)
predicted_lables = np.argmax(y_pred, axis = 1)
cm = confusion_matrix(test_labels, predicted_lables)
1/123 [..............................] - ETA: 38s
2023-03-17 12:10:44.685157: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
123/123 [==============================] - 9s 74ms/step
# dataframe containing the confussion matrix
cfm = pd.DataFrame(cm, index = class_names, columns = class_names)
# plotting the conffusion matrix
sns.heatmap(cfm, annot=True, fmt='d', cmap='Purples')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.xticks(rotation=78)
plt.title("Trasnfer Learning (non-trainable)", size = 15)
plt.show()
print("Preicision score:", precision_score(test_labels, predicted_lables, average="weighted"))
print("Recall score:", recall_score(test_labels, predicted_lables, average = "weighted"))
print("F1_score:", f1_score(test_labels, predicted_lables, average = "weighted"))
Preicision score: 0.983987378796772 Recall score: 0.9839490445859873 F1_score: 0.9839410264981292
# importing the test datest again, so that this time images can be shuffled
# so that displayed images are not ordered in the same way as in the dataset
# and variety of classes can be seen
test_data_shuffled = tf.keras.utils.image_dataset_from_directory(test_dir, shuffle = True, seed = 247)
Found 3925 files belonging to 10 classes.
def right_format_image(pic):
'''
This function returns a
reshaped image into 224x224
format in terms of height and
width.
Further it normalizes the
pixel values within the range
of [0, 1].
'''
img_size = (224, 224)
image = tf.image.resize(pic, img_size)
image_expanded = np.expand_dims(image, axis=0)
image_copy = np.copy(image_expanded)
normalized = image_copy/255.
return normalized
def data_iterator(data):
'''
This function returns as arrays the
components of a batch.
'''
iterator = data.as_numpy_iterator()
batch = iterator.next()
return batch
# plotting images from the test dataset, with their actual and predicted from the model labels
predicted_batch = data_iterator(test_data_shuffled)
plt.figure(figsize=(12, 12))
plt.subplots_adjust(hspace = .1, wspace=.3)
plt.suptitle("Trasnfer Learning (non-trainable)", size = 15)
for i in range(9):
image, label = predicted_batch[0][i], predicted_batch[1][i]
predictions = model_non_trainable.predict(right_format_image(image))
prediction_label = class_names[predictions.argmax()]
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image.astype(np.uint8))
plt.title("Actual label:{};\nPredicted label:{}".format(class_names[label],
class_names[predictions.argmax()]), size = 9)
plt.axis("off")
2023-03-17 12:10:54.625891: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
1/1 [==============================] - 0s 345ms/step 1/1 [==============================] - 0s 15ms/step 1/1 [==============================] - 0s 15ms/step 1/1 [==============================] - 0s 15ms/step 1/1 [==============================] - 0s 16ms/step 1/1 [==============================] - 0s 14ms/step 1/1 [==============================] - 0s 15ms/step 1/1 [==============================] - 0s 14ms/step 1/1 [==============================] - 0s 15ms/step
# reintroduce MobileNet
mobile = tf.keras.applications.mobilenet.MobileNet()
# replace last 5 layers with our own 2 dense layers
x_remove_layers = mobile.layers[-5].output
output_trainable = Dense(units = 10, activation = "softmax")(x_remove_layers)
output_trainable = tf.keras.layers.Reshape(target_shape=(10,))(output_trainable)
# create module, that takes MobileNet and transforms it with our desired final layers,
# in place of the MobileNet's last 5 layers
model_trainable = Model(inputs = mobile.input, outputs = output_trainable)
# unfreeze the last 24 of the just created above module, so that they are trainable,
# and their weights and biases will be updated (but only for those 24 final layers)
for layer in model_trainable.layers[:-24]:
layer.trainable = False
model_trainable.compile(optimizer = Adam(learning_rate = 0.0001), loss = "categorical_crossentropy", metrics = ["accuracy"])
# when 24 layers are made trainable, it can be noticed that there
# are much more trainable parameters, roughly 2 million in this case
model_trainable.summary()
Model: "model_1"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_2 (InputLayer) [(None, 224, 224, 3)] 0
conv1 (Conv2D) (None, 112, 112, 32) 864
conv1_bn (BatchNormalizatio (None, 112, 112, 32) 128
n)
conv1_relu (ReLU) (None, 112, 112, 32) 0
conv_dw_1 (DepthwiseConv2D) (None, 112, 112, 32) 288
conv_dw_1_bn (BatchNormaliz (None, 112, 112, 32) 128
ation)
conv_dw_1_relu (ReLU) (None, 112, 112, 32) 0
conv_pw_1 (Conv2D) (None, 112, 112, 64) 2048
conv_pw_1_bn (BatchNormaliz (None, 112, 112, 64) 256
ation)
conv_pw_1_relu (ReLU) (None, 112, 112, 64) 0
conv_pad_2 (ZeroPadding2D) (None, 113, 113, 64) 0
conv_dw_2 (DepthwiseConv2D) (None, 56, 56, 64) 576
conv_dw_2_bn (BatchNormaliz (None, 56, 56, 64) 256
ation)
conv_dw_2_relu (ReLU) (None, 56, 56, 64) 0
conv_pw_2 (Conv2D) (None, 56, 56, 128) 8192
conv_pw_2_bn (BatchNormaliz (None, 56, 56, 128) 512
ation)
conv_pw_2_relu (ReLU) (None, 56, 56, 128) 0
conv_dw_3 (DepthwiseConv2D) (None, 56, 56, 128) 1152
conv_dw_3_bn (BatchNormaliz (None, 56, 56, 128) 512
ation)
conv_dw_3_relu (ReLU) (None, 56, 56, 128) 0
conv_pw_3 (Conv2D) (None, 56, 56, 128) 16384
conv_pw_3_bn (BatchNormaliz (None, 56, 56, 128) 512
ation)
conv_pw_3_relu (ReLU) (None, 56, 56, 128) 0
conv_pad_4 (ZeroPadding2D) (None, 57, 57, 128) 0
conv_dw_4 (DepthwiseConv2D) (None, 28, 28, 128) 1152
conv_dw_4_bn (BatchNormaliz (None, 28, 28, 128) 512
ation)
conv_dw_4_relu (ReLU) (None, 28, 28, 128) 0
conv_pw_4 (Conv2D) (None, 28, 28, 256) 32768
conv_pw_4_bn (BatchNormaliz (None, 28, 28, 256) 1024
ation)
conv_pw_4_relu (ReLU) (None, 28, 28, 256) 0
conv_dw_5 (DepthwiseConv2D) (None, 28, 28, 256) 2304
conv_dw_5_bn (BatchNormaliz (None, 28, 28, 256) 1024
ation)
conv_dw_5_relu (ReLU) (None, 28, 28, 256) 0
conv_pw_5 (Conv2D) (None, 28, 28, 256) 65536
conv_pw_5_bn (BatchNormaliz (None, 28, 28, 256) 1024
ation)
conv_pw_5_relu (ReLU) (None, 28, 28, 256) 0
conv_pad_6 (ZeroPadding2D) (None, 29, 29, 256) 0
conv_dw_6 (DepthwiseConv2D) (None, 14, 14, 256) 2304
conv_dw_6_bn (BatchNormaliz (None, 14, 14, 256) 1024
ation)
conv_dw_6_relu (ReLU) (None, 14, 14, 256) 0
conv_pw_6 (Conv2D) (None, 14, 14, 512) 131072
conv_pw_6_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_6_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_7 (DepthwiseConv2D) (None, 14, 14, 512) 4608
conv_dw_7_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_dw_7_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_7 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_7_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_7_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_8 (DepthwiseConv2D) (None, 14, 14, 512) 4608
conv_dw_8_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_dw_8_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_8 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_8_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_8_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_9 (DepthwiseConv2D) (None, 14, 14, 512) 4608
conv_dw_9_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_dw_9_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_9 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_9_bn (BatchNormaliz (None, 14, 14, 512) 2048
ation)
conv_pw_9_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_10 (DepthwiseConv2D (None, 14, 14, 512) 4608
)
conv_dw_10_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_dw_10_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_10 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_10_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_pw_10_relu (ReLU) (None, 14, 14, 512) 0
conv_dw_11 (DepthwiseConv2D (None, 14, 14, 512) 4608
)
conv_dw_11_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_dw_11_relu (ReLU) (None, 14, 14, 512) 0
conv_pw_11 (Conv2D) (None, 14, 14, 512) 262144
conv_pw_11_bn (BatchNormali (None, 14, 14, 512) 2048
zation)
conv_pw_11_relu (ReLU) (None, 14, 14, 512) 0
conv_pad_12 (ZeroPadding2D) (None, 15, 15, 512) 0
conv_dw_12 (DepthwiseConv2D (None, 7, 7, 512) 4608
)
conv_dw_12_bn (BatchNormali (None, 7, 7, 512) 2048
zation)
conv_dw_12_relu (ReLU) (None, 7, 7, 512) 0
conv_pw_12 (Conv2D) (None, 7, 7, 1024) 524288
conv_pw_12_bn (BatchNormali (None, 7, 7, 1024) 4096
zation)
conv_pw_12_relu (ReLU) (None, 7, 7, 1024) 0
conv_dw_13 (DepthwiseConv2D (None, 7, 7, 1024) 9216
)
conv_dw_13_bn (BatchNormali (None, 7, 7, 1024) 4096
zation)
conv_dw_13_relu (ReLU) (None, 7, 7, 1024) 0
conv_pw_13 (Conv2D) (None, 7, 7, 1024) 1048576
conv_pw_13_bn (BatchNormali (None, 7, 7, 1024) 4096
zation)
conv_pw_13_relu (ReLU) (None, 7, 7, 1024) 0
global_average_pooling2d_1 (None, 1, 1, 1024) 0
(GlobalAveragePooling2D)
dense_1 (Dense) (None, 1, 1, 10) 10250
reshape_1 (Reshape) (None, 10) 0
=================================================================
Total params: 3,239,114
Trainable params: 1,873,930
Non-trainable params: 1,365,184
_________________________________________________________________
history_trainable = model_trainable.fit(x = train_batches,
validation_data = validation_batches,
epochs = 20)
Epoch 1/20
2023-03-17 12:10:56.817475: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
237/237 [==============================] - ETA: 0s - loss: 0.3222 - accuracy: 0.9050
2023-03-17 12:11:20.873431: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
237/237 [==============================] - 29s 119ms/step - loss: 0.3222 - accuracy: 0.9050 - val_loss: 0.1570 - val_accuracy: 0.9535 Epoch 2/20 237/237 [==============================] - 28s 117ms/step - loss: 0.0553 - accuracy: 0.9877 - val_loss: 0.1078 - val_accuracy: 0.9693 Epoch 3/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0248 - accuracy: 0.9966 - val_loss: 0.0789 - val_accuracy: 0.9778 Epoch 4/20 237/237 [==============================] - 28s 117ms/step - loss: 0.0121 - accuracy: 0.9992 - val_loss: 0.0844 - val_accuracy: 0.9736 Epoch 5/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0079 - accuracy: 0.9999 - val_loss: 0.0796 - val_accuracy: 0.9778 Epoch 6/20 237/237 [==============================] - 28s 117ms/step - loss: 0.0060 - accuracy: 0.9997 - val_loss: 0.0773 - val_accuracy: 0.9778 Epoch 7/20 237/237 [==============================] - 28s 117ms/step - loss: 0.0044 - accuracy: 0.9999 - val_loss: 0.0768 - val_accuracy: 0.9783 Epoch 8/20 237/237 [==============================] - 28s 117ms/step - loss: 0.0032 - accuracy: 1.0000 - val_loss: 0.0736 - val_accuracy: 0.9783 Epoch 9/20 237/237 [==============================] - 28s 119ms/step - loss: 0.0027 - accuracy: 1.0000 - val_loss: 0.0697 - val_accuracy: 0.9810 Epoch 10/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0021 - accuracy: 1.0000 - val_loss: 0.0732 - val_accuracy: 0.9804 Epoch 11/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0017 - accuracy: 1.0000 - val_loss: 0.0754 - val_accuracy: 0.9820 Epoch 12/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0017 - accuracy: 1.0000 - val_loss: 0.0714 - val_accuracy: 0.9815 Epoch 13/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0017 - accuracy: 1.0000 - val_loss: 0.0803 - val_accuracy: 0.9794 Epoch 14/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0012 - accuracy: 0.9999 - val_loss: 0.0810 - val_accuracy: 0.9783 Epoch 15/20 237/237 [==============================] - 28s 118ms/step - loss: 0.0010 - accuracy: 1.0000 - val_loss: 0.0737 - val_accuracy: 0.9810 Epoch 16/20 237/237 [==============================] - 28s 118ms/step - loss: 9.2186e-04 - accuracy: 1.0000 - val_loss: 0.0771 - val_accuracy: 0.9794 Epoch 17/20 237/237 [==============================] - 28s 118ms/step - loss: 7.5540e-04 - accuracy: 1.0000 - val_loss: 0.0901 - val_accuracy: 0.9767 Epoch 18/20 237/237 [==============================] - 28s 118ms/step - loss: 8.0109e-04 - accuracy: 1.0000 - val_loss: 0.0923 - val_accuracy: 0.9767 Epoch 19/20 237/237 [==============================] - 28s 118ms/step - loss: 9.6637e-04 - accuracy: 0.9999 - val_loss: 0.0929 - val_accuracy: 0.9746 Epoch 20/20 237/237 [==============================] - 28s 118ms/step - loss: 8.2548e-04 - accuracy: 1.0000 - val_loss: 0.0823 - val_accuracy: 0.9757
# Graphical evaluation of training performance
acc = history_trainable.history['accuracy']
val_acc = history_trainable.history['val_accuracy']
loss = history_trainable.history['loss']
val_loss = history_trainable.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(11, 8))
plt.subplots_adjust(hspace = .3)
plt.subplot(2, 1, 1)
plt.plot(epochs_range, acc, label = 'Training Accuracy', color = "orange")
plt.plot(epochs_range, val_acc, label = 'Validation Accuracy', color = "blue")
plt.legend(loc = 'best')
plt.xlabel('Epochs')
plt.title('Training and Validation Accuracy', size = 13)
plt.subplot(2, 1, 2)
plt.plot(epochs_range, loss, label = 'Training Loss', color = "orange")
plt.plot(epochs_range, val_loss, label = 'Validation Loss', color = "blue")
plt.legend(loc = 'best')
plt.title('Training and Validation Loss', size = 13)
plt.xlabel('Epochs')
plt.suptitle("Transfer learning (trainable)", size=15)
plt.show()
# Test loss and accuracy measurments
test_loss, test_acc = model_trainable.evaluate(test_batches)
print('Test loss:', test_loss)
print('Test accuracy:', test_acc)
123/123 [==============================] - 9s 77ms/step - loss: 0.0717 - accuracy: 0.9786 Test loss: 0.07172290980815887 Test accuracy: 0.9785987734794617
# getting prediction labales by running the softmax results in argmax
test_labels_trainable = test_batches.classes
y_pred_trainable = model_trainable.predict(test_batches)
predicted_lables_trainable = np.argmax(y_pred_trainable, axis = 1)
cm_trainable = confusion_matrix(test_labels_trainable, predicted_lables_trainable)
2023-03-17 12:20:27.342018: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
123/123 [==============================] - 9s 74ms/step
# dataframe containing the confussion matrix
cfm_trainable = pd.DataFrame(cm_trainable, index = class_names, columns = class_names)
# plotting the conffusion matrix
sns.heatmap(cfm_trainable, annot=True, fmt='d', cmap='Purples')
plt.xlabel('Predicted Label')
plt.ylabel('True Label')
plt.xticks(rotation=78)
plt.title("Trasnfer Learning (trainable)", size = 15)
plt.show()
print("Preicision score:", precision_score(test_labels_trainable, predicted_lables_trainable, average="weighted"))
print("Recall score:", recall_score(test_labels_trainable, predicted_lables_trainable, average="weighted"))
print("F1_score:", f1_score(test_labels_trainable, predicted_lables_trainable, average="weighted"))
Preicision score: 0.9787801523100653 Recall score: 0.9785987261146497 F1_score: 0.9785276559550272
# plotting images from the test dataset, with their actual and predicted from the model labels
predicted_batch = data_iterator(test_data_shuffled)
plt.figure(figsize=(12, 12))
plt.subplots_adjust(hspace = .1, wspace=.3)
plt.suptitle("Trasnfer Learning (trainable)", size = 15)
for i in range(9):
image, label = predicted_batch[0][i], predicted_batch[1][i]
predictions = model_trainable.predict(right_format_image(image))
prediction_label = class_names[predictions.argmax()]
ax = plt.subplot(3, 3, i + 1)
plt.imshow(image.astype(np.uint8))
plt.title("Actual label:{};\nPredicted label:{}".format(class_names[label],
class_names[predictions.argmax()]), size = 9)
plt.axis("off")
1/1 [==============================] - 0s 246ms/step
2023-03-17 12:20:37.127066: I tensorflow/core/grappler/optimizers/custom_graph_optimizer_registry.cc:113] Plugin optimizer for device_type GPU is enabled.
1/1 [==============================] - 0s 18ms/step 1/1 [==============================] - 0s 22ms/step 1/1 [==============================] - 0s 15ms/step 1/1 [==============================] - 0s 16ms/step 1/1 [==============================] - 0s 14ms/step 1/1 [==============================] - 0s 17ms/step 1/1 [==============================] - 0s 15ms/step 1/1 [==============================] - 0s 14ms/step